#include <string.h>
#include "osip_message_parse.h"
#include "comm-func.h"
#include <QString>
#include <QDebug>

bool osip_message_parse_xml_body(char *p_xml_body, Cmd_Header *&p_cmd)
{
    //fprintf(stdout, "osip mesage parse xml body: %s\n", p_xml_body);

    std::string str_cmd_type = FindField(p_xml_body, "<CmdType>", "</CmdType>", strlen(p_xml_body));
    std::string str_sn = FindField(p_xml_body, "<SN>", "</SN>", strlen(p_xml_body));
    std::string str_device_id = FindField(p_xml_body, "<DeviceID>", "</DeviceID>", strlen(p_xml_body));

    if(str_cmd_type.empty() || str_sn.empty() || str_device_id.empty()){
        return false;
    }

    bool b_ret = false;

    std::string str_response = FindField(p_xml_body, "<Response>", "</Response>", strlen(p_xml_body));
    if(!str_response.empty()){
        //Response Catalog
        if( 0 == strcmp(str_cmd_type.c_str(), "Catalog")){
            b_ret = osip_message_parse_xml_body_response_catalog((char *)str_response.c_str(), p_cmd);
        } else if(0 == strcmp(str_cmd_type.c_str(), "DeviceInfo")){
            b_ret = osip_message_parse_xml_body_response_deviceinfo((char *)str_response.c_str(), p_cmd);
        } else if(0 == strcmp(str_cmd_type.c_str(), "DeviceStatus")){
            b_ret = osip_message_parse_xml_body_response_devicestatus((char *)str_response.c_str(), p_cmd);
        } else if(0 == strcmp(str_cmd_type.c_str(), "PresetQuery")){
            b_ret = osip_message_parse_xml_body_response_preset_list((char *)str_response.c_str(), p_cmd);
        } else if(0 == strcmp(str_cmd_type.c_str(), "RecordInfo")){
            b_ret = osip_message_parse_xml_body_response_record_info((char *)str_response.c_str(), p_cmd);
        }
    }

    std::string str_notify = FindField(p_xml_body, "<Notify>", "</Notify>", strlen(p_xml_body));
    if(!str_notify.empty()){
        if(0 == strcmp(str_cmd_type.c_str(), "MediaStatus")){
            b_ret = osip_message_parse_xml_body_mediastatus((char *)str_response.c_str(), p_cmd);
        }
    }

    if(b_ret && (p_cmd != nullptr)){
        p_cmd->m_str_cmd_type = str_cmd_type;
        p_cmd->m_str_seqno = str_sn;
        p_cmd->m_str_device_id = str_device_id;
    }

    return b_ret;
}

bool osip_message_parse_xml_body_response_catalog(char *p_xml_body, Cmd_Header *&p_cmd)
{
    Catalog_Response *pst_response_catalog = new Catalog_Response();
    pst_response_catalog->mi_cmd_type = Cmd_Type_Device_Response;

    std::string str_sum_num = FindField(p_xml_body, "<SumNum>", "</SumNum>", strlen(p_xml_body));
    std::string str_device_list = FindField(p_xml_body, "<DeviceList", "</DeviceList>", strlen(p_xml_body));
    std::string str_num = FindField(str_device_list.c_str(), "Num=", ">", str_device_list.length());
    if(str_num[0] == '\"'){
        str_num = str_num.substr(1, str_num.length() - 2);
    }

    while(true){
        std::string str_device_item = FindField(str_device_list.c_str(), "<Item>", "</Item>", str_device_list.length());
        if(str_device_item.empty()){
            break;
        }

        Device_Channel st_device_channel;
        st_device_channel.str_device_channel_id = FindField(str_device_item.c_str(), "<DeviceID>", "</DeviceID>", str_device_item.length());
        st_device_channel.str_name = FindField(str_device_item.c_str(), "<Name>", "</Name>", str_device_item.length());
        st_device_channel.str_manufacturer = FindField(str_device_item.c_str(), "<Manufacturer>", "</Manufacturer>", str_device_item.length());
        st_device_channel.str_model = FindField(str_device_item.c_str(), "<Model>", "</Model>", str_device_item.length());
        st_device_channel.str_address = FindField(str_device_item.c_str(), "<Address>", "</Address>", str_device_item.length());
        st_device_channel.str_parent_id = FindField(str_device_item.c_str(), "<ParentID>", "</ParentID>", str_device_item.length());
        st_device_channel.str_status = FindField(str_device_item.c_str(), "<Status>", "</Status>", str_device_item.length());

        pst_response_catalog->st_channel_vec.push_back(st_device_channel);

        str_device_list = str_device_list.substr(str_device_item.length());
    }

    pst_response_catalog->i_sunnum = atoi(str_sum_num.c_str());
    p_cmd = pst_response_catalog;
    return true;
}

bool osip_message_parse_xml_body_response_deviceinfo(char *p_xml_body, Cmd_Header *&p_cmd)
{
    DeviceInfo_Response *pst_response_deviceinfo = new DeviceInfo_Response();
    pst_response_deviceinfo->mi_cmd_type = Cmd_Type_Device_Response;

    pst_response_deviceinfo->str_result = FindField(p_xml_body, "<Result>", "</Result>", strlen(p_xml_body));
    pst_response_deviceinfo->str_device_name = FindField(p_xml_body, "<DeviceName>", "</DeviceName>", strlen(p_xml_body));
    pst_response_deviceinfo->str_manufacturer = FindField(p_xml_body, "<Manufacturer>", "</Manufacturer>", strlen(p_xml_body));
    pst_response_deviceinfo->str_model = FindField(p_xml_body, "<Model>", "</Model>", strlen(p_xml_body));
    pst_response_deviceinfo->str_fireware = FindField(p_xml_body, "<Fireware>", "</Fireware>", strlen(p_xml_body));
    std::string str_channel_num = FindField(p_xml_body, "<Channel>", "</Channel>", strlen(p_xml_body));
    pst_response_deviceinfo->i_channel_num = atoi(str_channel_num.c_str());

    p_cmd = pst_response_deviceinfo;
    return true;
}

bool osip_message_parse_xml_body_response_devicestatus(char *p_xml_body, Cmd_Header *&p_cmd)
{
    DeviceStatus_Response *pst_response_devicestatus = new DeviceStatus_Response();
    pst_response_devicestatus->mi_cmd_type = Cmd_Type_Device_Response;

    pst_response_devicestatus->str_result = FindField(p_xml_body, "<Result>", "</Result>", strlen(p_xml_body));
    pst_response_devicestatus->str_online = FindField(p_xml_body, "<Online>", "</Online>", strlen(p_xml_body));
    pst_response_devicestatus->str_status = FindField(p_xml_body, "<Status>", "</Status>", strlen(p_xml_body));
    pst_response_devicestatus->str_device_time = FindField(p_xml_body, "<DeviceTime>", "</DeviceTime>", strlen(p_xml_body));
    pst_response_devicestatus->str_encode = FindField(p_xml_body, "<Encode>", "</Encode>", strlen(p_xml_body));
    pst_response_devicestatus->str_record = FindField(p_xml_body, "<Record>", "</Record>", strlen(p_xml_body));

    p_cmd = pst_response_devicestatus;
    return true;
}

bool osip_message_parse_xml_body_response_preset_list(char *p_xml_body, Cmd_Header *&p_cmd)
{
    PresetList_Response *pst_response = new PresetList_Response();
    pst_response->mi_cmd_type = Cmd_Type_Device_Response;

    std::string str_preset_list = FindField(p_xml_body, "<PresetList", "</PresetList>", strlen(p_xml_body));
    std::string str_num = FindField(str_preset_list.c_str(), "Num=", ">", str_preset_list.length());
    if(str_num[0] == '\"'){
        str_num = str_num.substr(1, str_num.length() - 2);
    }

    while(true){
        std::string str_preset_item = FindField(str_preset_list.c_str(), "<Item>", "</Item>", str_preset_list.length());
        if(str_preset_item.empty()){
            break;
        }

        Preset_Item st_item;
        std::string str_preset_id = FindField(str_preset_item.c_str(), "<PresetID>", "</PresetID>", str_preset_item.length());
        st_item.str_preset_name = FindField(str_preset_item.c_str(), "<PresetName>", "</PresetName>", str_preset_item.length());
        st_item.i_id = atoi(str_preset_id.c_str());

        QString qstr_name(QString::fromLocal8Bit(st_item.str_preset_name.c_str()));

        qDebug() << qstr_name;

        pst_response->st_preset_vec.push_back(st_item);

        str_preset_list = str_preset_list.substr(str_preset_item.length());
    }

    p_cmd = pst_response;
    return true;
}

bool osip_message_parse_xml_body_response_record_info(char *p_xml_body, Cmd_Header *&p_cmd)
{
    RecordInfo_Response *pst_response = new RecordInfo_Response();
    pst_response->mi_cmd_type = Cmd_Type_Device_Response;

    std::string str_name = FindField(p_xml_body, "<Name>", "</Name>", strlen(p_xml_body));
    std::string str_sum_num = FindField(p_xml_body, "<SumNum>", "</SumNum>", strlen(p_xml_body));
    pst_response->str_name = str_name;
    pst_response->i_sum_num = atoi(str_sum_num.c_str());

    std::string str_record_list = FindField(p_xml_body, "<RecordList", "</RecordList>", strlen(p_xml_body));
    std::string str_num = FindField(str_record_list.c_str(), "Num=", ">", str_record_list.length());
    if(str_num[0] == '\"'){
        str_num = str_num.substr(1, str_num.length() - 2);
    }

    while(true){
        std::string str_record_item = FindField(str_record_list.c_str(), "<Item>", "</Item>", str_record_list.length());
        if(str_record_item.empty()){
            break;
        }

        Record_Info_Item st_item;
        st_item.str_device_id = FindField(str_record_item.c_str(), "<DeviceID>", "</DeviceID>", str_record_item.length());
        st_item.str_name = FindField(str_record_item.c_str(), "<Name>", "</Name>", str_record_item.length());
        st_item.str_file_path = FindField(str_record_item.c_str(), "<FilePath>", "</FilePath>", str_record_item.length());
        st_item.str_address = FindField(str_record_item.c_str(), "<Address>", "</Address>", str_record_item.length());
        st_item.str_start_time = FindField(str_record_item.c_str(), "<StartTime>", "</StartTime>", str_record_item.length());
        st_item.str_end_time = FindField(str_record_item.c_str(), "<EndTime>", "</EndTime>", str_record_item.length());
        std::string str_secrecy = FindField(str_record_item.c_str(), "<Secrecy>", "</Secrecy>", str_record_item.length());
        st_item.str_type = FindField(str_record_item.c_str(), "<Type>", "</Type>", str_record_item.length());
        std::string str_file_size = FindField(str_record_item.c_str(), "<FileSize>", "</FileSize>", str_record_item.length());

        st_item.i_secrecy = atoi(str_secrecy.c_str());
        st_item.ui_file_size = atoi(str_file_size.c_str());

        pst_response->st_record_info_vec.push_back(st_item);

        str_record_list = str_record_list.substr(str_record_item.length());
    }

    p_cmd = pst_response;
    return true;
}

bool osip_message_parse_xml_body_mediastatus(char *p_xml_body, Cmd_Header *&p_cmd)
{
    MediaStatus_Notify *pst_notify = new MediaStatus_Notify();
    pst_notify->mi_cmd_type = Cmd_Type_Notify;

    std::string str_type = FindField(p_xml_body, "<NotifyType>", "</NotifyType>", strlen(p_xml_body));
    pst_notify->str_notify_type = str_type;

    p_cmd = pst_notify;
    return true;
}
